//
//  HTTPClient.swift
//  YiLinkerOnlineBuyer
//
//  Created by zhengxuening on 16/3/11.
//  Copyright © 2016年 yiLinker-online-buyer. All rights reserved.
//

/**
 网络请求封装类
 */

import UIKit
import AFNetworking

enum RequestErrorType {
    case NoInternetConnection  // 没有网络连接
    case RequestTimeOut        // 请求超时
    case PageNotFound          // 页面没有找到
    case ResponseError         // 请求成功,但在服务器遇到错误
    case NoError               // 没有错误
    case Cancel                // 取消
}

/// 函数回调别名
//typealias httpClosure = (_ successful: Bool, _ responseJSON: Any?, _ requestErrorType: RequestErrorType) -> Void
typealias httpClosure = (_ successful: Bool, _ responseJSON: Any?) -> Void

class HTTPClient: NSObject {
    
    /**
     *  服务器返回码
     */
    struct WebServiceStatusCode {
        static let pageNotFound: Int = 404
    }
    
    /// 网络请求个数
    var taskCount = 0
    
    var dicTask = [String: URLSessionDataTask]()
    
    /// 单例
    static let sharedInstance:HTTPClient = {
        let client = HTTPClient()
        return client
    }()
    
    // MARK: - 私有init
    private override init() {}
    
    // MARK: - 请求方法
    // MARK: - GET方法
    static func get(url:String, params:[String:Any]?, httpName:String?, closure:@escaping httpClosure) ->URLSessionDataTask? {
        
        #file
        return HTTPClient.sharedInstance.request(url: url, params: params, httpName:httpName, isPOST: false, closure: closure)
    }
    
    // MARK: - POST方法
    static func post(url:String, params:[String:Any]?, httpName:String?, closure:@escaping httpClosure) ->URLSessionDataTask {
        return HTTPClient.sharedInstance.request(url: url, params: params, httpName:httpName, isPOST: true, closure: closure)
    }
    
    private func request(url:String, params:[String:Any]?, httpName:String?, isPOST:Bool, closure:@escaping httpClosure) ->URLSessionDataTask {
        let manager:AFHTTPSessionManager = AFHTTPSessionManager(baseURL: nil)
        manager.responseSerializer = AFHTTPResponseSerializer()
        manager.requestSerializer.willChangeValue(forKey: "timeoutInterval")
        manager.requestSerializer.timeoutInterval = 20.0
        manager.requestSerializer.didChangeValue(forKey: "timeoutInterval")
        var sessionDataTask:URLSessionDataTask?
        let sAllURL = url
        
        if isPOST{
            sessionDataTask = manager.post(sAllURL, parameters: params, progress: nil, success: { (task, responseObject) in
                if responseObject == nil {
                    print("报错,POST请求：\(sAllURL)  返回数据为空 \n")
                    // 服务器遇到错误
                    closure(false, nil)
                    return
                }
                //                let json = JSON(data: responseObject as! NSData)
                closure(true, responseObject)
                //网络请求-1
                self.decreaseTaskCount()
                self.delTaskId(httpName: httpName!)
                }, failure: { (task, error) in
                    if let task = task!.response as? HTTPURLResponse {
                        if task.statusCode == WebServiceStatusCode.pageNotFound {
                            // 页面没有找到
                            closure(false, nil)
                        } else {
                            // 服务器遇到错误
                            closure(false, nil)
                        }
                    } else {
                        // 取消
                        closure(false, nil)
                    }
                    //网络请求-1
                    self.decreaseTaskCount()
                    self.delTaskId(httpName: httpName!)
                    print("********网络请求分割线********\n POST请求失败：\(sAllURL) \n 错误提示：\(error) \n ********网络请求分割线********")
                    
            })
        } else {
            sessionDataTask = manager.get(sAllURL, parameters: nil, progress: nil, success: { (task, responseObject) in
                if responseObject == nil {
                    print("报错,POST请求：\(sAllURL)  返回数据为空 \n")
                    // 服务器遇到错误
                    closure(false, nil)
                    //网络请求-1
                    self.decreaseTaskCount()
                    self.delTaskId(httpName: httpName!)
                    return
                }
                
                //                let json = JSON(data: responseObject as! NSData)
                closure(true, responseObject)
                //网络请求-1
                self.decreaseTaskCount()
                self.delTaskId(httpName: httpName!)
                }, failure: { (task, error) in
                    if let task = task!.response as? HTTPURLResponse {
                        if task.statusCode == WebServiceStatusCode.pageNotFound {
                            // 页面没有找到
                            closure(false, nil)
                        } else {
                            // 服务器遇到错误
                            closure(false, nil)
                        }
                    } else {
                        // 取消
                        closure(false, nil)
                    }
                    //网络请求-1
                    self.decreaseTaskCount()
                    self.delTaskId(httpName: httpName!)
                    print("********网络请求分割线********\n GET请求失败：\(sAllURL) \n 错误提示：\(error) \n ********网络请求分割线********")
            })
        }
        if httpName != nil {
            dicTask[httpName!] = sessionDataTask
        }
        // 网络请求+1
        increaseTaskCount()
        return sessionDataTask!
    }
    
    /// 通过httpName取消单个网络请求
    static func cancelSigleTask(httpName: String) {
        HTTPClient.sharedInstance.cancelSigleTask(httpName: httpName)
    }
    
    /// 取消所有网络请求
    func cancelAllTask() {
        for obj in dicTask {
            HTTPClient.sharedInstance.cancelSigleTask(httpName: obj.key)
        }
    }
    
    // 取消网络请求，根据key删除字典dicTask里面的value
    private func cancelSigleTask(httpName: String) {
        if let task = dicTask[httpName] {
            task.cancel()
            delTaskId(httpName: httpName)
            print("\(httpName) 已经成功取消")
        }
    }
    
    private func delTaskId(httpName: String?) {
        if httpName != nil {
            if let value = dicTask.removeValue(forKey: httpName!) {
                print("The value \(value) was removed.")
            }
        }
    }
    
    /// 网络请求总数+1
    private func increaseTaskCount() {
        // 加线程安全?
        taskCount += 1
        toggleNetworkActivityIndicator()
    }
    
    /// 网络请求总数-1
    private func decreaseTaskCount() {
        // 加线程安全?
        taskCount -= 1
        toggleNetworkActivityIndicator()
    }
    
    /// 判断菊花转动
    private func toggleNetworkActivityIndicator() {

        print("当前网络请求个数 = \(taskCount)")
        UIApplication.shared.isNetworkActivityIndicatorVisible = taskCount > 0
    }
    
}
